package com.mars.push.core.response;

import lombok.Data;

/**
 * 公共响应的实体
 *
 * @author : mjy
 * @date : 2020-06-18
 **/
@Data
public class R<T> {

    /**
     * 状态码
     */
    private String status;
    /**
     * 说明
     */
    private String msg;
    /**
     * 数据
     */
    private T data;

    /**
     * 构建一个R对象
     * 使用静态方法{@link #result(Object, String, String)}
     *
     * @param status 状态码
     * @param msg    消息
     * @param data   数据
     */
    private R(String status, String msg, T data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    /**
     * 无参数成功返回
     *
     * @return R
     */
    public static <T> R<T> ok() {
        return ok(null);
    }

    public static <T> R<T> success() {
        return ok(null);
    }

    /**
     * 有数据成功返回
     *
     * @param data 数据
     * @param <T>  数据类型
     * @return R
     */
    public static <T> R<T> ok(T data) {
        return ok(data, ResponseCode.SUCCESS.getMsg());
    }

    /**
     * 字符串数据成功返回
     *
     * @param str 字符串
     * @return R
     */
    public static R<String> okString(String str) {
        return ok(str, ResponseCode.SUCCESS.getMsg());
    }

    /**
     * 指定消息提示成功返回
     *
     * @param msg 消息
     * @return R
     */
    public static <T> R<T> ok(String msg) {
        return ok(null, msg);
    }

    /**
     * 指定数据和提示信息成功返回
     *
     * @param data 数据
     * @param msg  消息
     * @param <T>  数据类型
     * @return R
     */
    public static <T> R<T> ok(T data, String msg) {
        return result(data, msg, ResponseCode.SUCCESS.getCode());
    }

    /**
     * 无参数失败返回
     *
     * @return R
     */
    public static <T> R<T> fail() {
        return fail(null);
    }

    /**
     * 指定消息提示失败返回
     *
     * @param msg 消息
     * @return R
     */
    public static <T> R<T> fail(String msg) {
        return fail(ResponseCode.FAIL.getCode(), msg);
    }

    /**
     * 指定的状态码和消息提示返回
     * 没有与错误有直接关系的提示和状态码，建议使用{@link #result(String, String)}
     *
     * @param code 状态码
     * @param msg  消息
     * @return R
     */
    public static <T> R<T> fail(String code, String msg) {
        return result(msg, code);
    }

    /**
     * 携带数据的成功返回
     * 重复方法，建议使用{@link #ok(Object)}
     *
     * @param data 数据
     * @param <T>  数据类型
     * @return R
     */
    public static <T> R<T> success(T data) {
        return ok(data);
    }

    /**
     * 获取成功返回实例
     * 重复方法，建议使用{@link #ok(Object, String)}
     *
     * @param data 数据
     * @param msg  消息
     * @param <T>  数据类型
     * @return R
     */

    public static <T> R<T> getSucceedInstance(T data, String msg) {
        return ok(data, msg);
    }

    /**
     * 获取失败返回实例
     * 建议使用{@link #result(String, String)}
     *
     * @param code 状态码
     * @param desc 提示信息
     * @return R
     */
    public static <T> R<T> getFailInstance(String code, String desc) {
        return result(desc, code);
    }

    /**
     * 指定消息/状态码的返回
     *
     * @param msg    消息
     * @param status 状态码
     * @param <T>    数据类型
     * @return R
     */
    public static <T> R<T> result(String msg, String status) {
        return result(null, msg, status);
    }

    /**
     * 指定数据/消息/状态码的返回
     *
     * @param data   数据
     * @param msg    消息
     * @param status 状态码
     * @param <T>    数据类型
     * @return R
     */
    public static <T> R<T> result(T data, String msg, String status) {
        return new R<>(status, msg, data);
    }

}
